

#ifndef EB_TFTP_SIMU_CLNT_H
#define EB_TFTP_SIMU_CLNT_H

#include <halether.h>

// copy from rndis.c
// Ethernet Frame
#define MAX_ETH_BLOCK 1520



class IEbootSimuBin
{
public:
//	virtual ~IEbootSimuBin(){};	// can't use virtual de

public:
    virtual BOOL Read(BYTE* pbBuf, WORD* pwLen)=0;
};

class CEbootSimuBin
	:public IEbootSimuBin
{
public:
    CEbootSimuBin(){};
public:
	BOOL Init(DWORD dwImgStart, DWORD dwImgLen, DWORD dwRecNumb);

public:
    BOOL Read(BYTE* pbBuf, WORD* pwLen);

private:
	DWORD CheckSum_FF(DWORD dwLen);

private:
	DWORD m_dwFileSize;
	DWORD m_dwImgStart;
	DWORD m_dwImgLen;
	DWORD m_dwRecSize;
	DWORD m_dwCurRecPos;
	DWORD m_dwCurHdPos;
	DWORD m_dwCurFilePos;

	DWORD m_dwRecInfo[3];

	DWORD m_dwLastPackageLen;
};

class CEbootMemBin
	:public IEbootSimuBin
{
public:
    CEbootMemBin(){};
public:
	BOOL Init(DWORD dwMemStart, DWORD dwMemLen);

public:
    BOOL Read(BYTE* pbBuf, WORD* pwLen);

private:
	BYTE* m_pMemStart;
	DWORD m_dwMemLen;
	DWORD m_dwCurPos;
};

class CEbTftpSimuClnt
{
#define TFTP_HEAD_LEN	(4)
#define TFTP_DATA_LEN	(512)
#define TFTP_PKT_LEN	(TFTP_HEAD_LEN + TFTP_DATA_LEN)
#define TFTP_PCKT_MIN_LEN	TFTP_HEAD_LEN

enum{ OP_RRQ=1,  OP_WRQ=2,	OP_DATA=3,	OP_ACK=4,  OP_ERR=5};
enum TFTPD_STAT{STAT_NONE=0, STAT_WRQ, STAT_RRQ,  STAT_WT_DATA,  STAT_RD_DATA,	STAT_ERR};

public:
	CEbTftpSimuClnt(){};
	BOOL Init(IEbootSimuBin* pFile, char* pszName);
	
public:
	// here is the tftp write request and write data packages
	BOOL EbootGetData(BYTE* pbuf, WORD* wLen);
	// here is the tftp ACK for above packages
	BOOL EbootSendData(BYTE* pbuf, DWORD dwLen);

private:
	BOOL MakeWRQPckt(BYTE* pbuf, WORD* pwLen);
	BOOL MakeWtDataHd(BYTE* pbuf, WORD* pwLen);
	VOID GetOpCodeBlkNum( BYTE* pbuf, WORD* pwOp, WORD* pwBlkNum);

private:
	char m_szFileName[TFTP_DATA_LEN];

	WORD m_wBlkNum;
	TFTPD_STAT m_State;

private:
	IEbootSimuBin* m_pFile;
};


class CEbSimuTransEther
{
public:
	CEbSimuTransEther(){};
	BOOL Init(EDBG_ADDR* pMyAddr, EDBG_ADDR* pDesAddr);

public:
	BOOL FormEthFrame(BYTE* pbufData, WORD wDataLen, BYTE* pbufEther, WORD* pwEtherLen);
	BOOL GetEtherPayload(BYTE* pbufEther, WORD wEtherLen, BYTE** ppDatabuf, DWORD* pdwDataLen);

private:
	BYTE m_buf[MAX_ETH_BLOCK];

	EDBG_ADDR	m_destAddr; 		 
	EDBG_ADDR	m_myAddr;		 
};


#endif 	//#ifndef EB_TFTP_SIMU_CLNT_H

